package controllers

import (
	"encoding/base64"
	"errmsg"
	"errors"
	"github.com/astaxie/beego/logs"
	"github.com/astaxie/beego/validation"
	"regexp"
	"smart_home/api/models"
	"smart_home/api/utils/aiui"
	"smart_home/api/utils/token"
	"strings"
	"tools"
)

// Operations about Users
type UserController struct {
	BaseController
}

// @Title Get
// @Description get user info
// @router /info [get]
func (c *UserController) Info() {
	c.Success(c.User)
}

// @Title Put
// @Description 修改用户信息
// @Param	nick_name		body 	string	true		"用户昵称"
// @Param	birthday		body 	string	true		"生日 如:2008-05-06"
// @Param	sex				body 	int64	true		"性别 0:男 1:女 2:未知"
// @Param	avatar			body 	string	true		"头像地址"
// @router /info [put]
func (c *UserController) Put() {
	var (
		user                     *models.User
		err                      error
		vali                     validation.Validation
		birthdayRegx, avatarRegx *regexp.Regexp
	)

	user = c.User

	err = c.ParseData(user)
	if err != nil {
		logs.Info(err)
		c.Error(errmsg.ErrResponseParameter)
		return
	}

	vali = validation.Validation{}
	vali.Required(user.NickName, "nick_name").Message("用户昵称不能为空")
	vali.Required(user.Birthday, "birthday").Message("生日不能为空")
	vali.Range(user.Sex, 0, 2, "sex").Message("性别不能为空")
	vali.Required(user.Avatar, "avatar").Message("头像不能为空")

	birthdayRegx = regexp.MustCompile(`^(19|20)\d{2}-(1[0-2]|0?[1-9])-(0?[1-9]|[1-2][0-9]|3[0-1])$`)
	vali.Match(user.Birthday, birthdayRegx, "birthday").Message("生日格式为:2018-09-05")
	vali.Range(user.Sex, 0, 2, "sex").Message("性别值为0,1,2")

	user.Avatar = strings.ToLower(user.Avatar)
	avatarRegx = regexp.MustCompile(`^(http|https):\/\/.+?(\.jpg|\.gif|\.png|\.jpeg)$`)
	vali.Match(user.Avatar, avatarRegx, "avatar").Message("头像地址不合法")
	if vali.HasErrors() {
		logs.Info(err)
		c.Error(vali.Errors[0])
		return
	}

	if err = models.UpdateUserById(user.Id, user.NickName, user.Birthday, user.Avatar, user.Sex); err != nil {
		logs.Info(err)
		c.Error(errmsg.ErrResponseSystem)
		return
	}

	// 上传动态实例
	aiui.UploadEntity(
		"rcenet_user",
		map[string]string{"nick_name": user.NickName},
		map[string]string{"system": "rcenet"})

	c.Success(nil)
}

// @Title Change Password
// @Description 修改密码
// @Param	password		body 	string	true		"new Password"
// @Param	oldpassword		body 	string	true		"old password"
// @router /password [put]
func (c *UserController) Password() {
	var (
		err                                error
		pwd, opwd, passDecode, opassDecode []byte
		ps                                 = &struct {
			Spwd  string `json:"password"`
			Sopwd string `json:"oldpassword"`
		}{}
	)

	if err = c.ParseData(ps); err != nil {
		logs.Error(err)
		c.Error(errmsg.ErrResponseSystem)
		return
	}

	vali := validation.Validation{}
	vali.Required(ps.Spwd, "password").Message("请输入新密码")
	vali.Required(ps.Sopwd, "oldpassword").Message("请输入旧密码")
	if vali.HasErrors() {
		logs.Debug(vali.Errors[0])
		c.Error(vali.Errors[0])
		return
	}

	if ps.Spwd == ps.Sopwd {
		err = errors.New("新密码和旧密码一致")
		logs.Info(err)
		c.Error(err)
		return
	}

	// base64解码
	passDecode, err = base64.StdEncoding.DecodeString(ps.Spwd)
	if err != nil {
		logs.Error(err)
		c.Error(errmsg.ErrResponseSystem)
		return
	}

	// rsa解密
	pwd, err = tools.Decrypt(passDecode)
	if err != nil {
		logs.Error(err)
		c.Error(errmsg.ErrResponseSystem)
		return
	}

	// base64解码
	opassDecode, err = base64.StdEncoding.DecodeString(ps.Sopwd)
	if err != nil {
		logs.Error(err)
		c.Error(errmsg.ErrResponseSystem)
		return
	}

	// rsa解密
	opwd, err = tools.Decrypt(opassDecode)
	if err != nil {
		logs.Error(err)
		c.Error(errmsg.ErrResponseSystem)
		return
	}

	vali.MaxSize(pwd, 18, "password").Message("新密码由6到18位字符组成")
	vali.MinSize(pwd, 6, "password").Message("新密码由6到18位字符组成")
	if vali.HasErrors() {
		logs.Info(err)
		c.Error(vali.Errors[0])
		return
	}

	if c.User.Password != tools.MD5Encode(string(opwd)) {
		err = errors.New("原密码不正确")
		logs.Info(err)
		c.Error(err)
		return
	}

	logs.Debug("pwd:", string(pwd))
	if err = models.ResetUserPassword(c.User.Mobile, string(pwd)); err != nil {
		logs.Info(err)
		c.Error(errmsg.ErrResponseSystem)
		return
	}

	// 极光通知用户下线
	models.PushMessage(c.User.Id, "您的密码已变更，请重新登陆", "login", map[string]interface{}{"action":"repassword"})

	c.Success(nil)
}

// @Title 退出登陆
// @router /logout [delete]
func (c *UserController) Logout() {
	if err := token.Del(c.User.Id, c.Token); err != nil {
		logs.Error("logout error:", err)
		c.Error(errmsg.ErrResponseSystem)
	}
	c.Success(nil)
}
